package top.liujingyanghui.crypto.tkmybatis.mapper;

import org.apache.ibatis.annotations.Param;
import tk.mybatis.mapper.common.Mapper;
import top.liujingyanghui.crypto.mybatis.annotation.CryptoKey;
import top.liujingyanghui.crypto.mybatis.annotation.CryptoKeys;
import top.liujingyanghui.crypto.mybatis.annotation.CryptoString;
import top.liujingyanghui.crypto.mybatis.annotation.CryptoStrings;
import top.liujingyanghui.crypto.mybatis.enums.CryptoMode;
import top.liujingyanghui.crypto.tkmybatis.entity.User;
import top.liujingyanghui.crypto.tkmybatis.param.UserParam;
import top.liujingyanghui.crypto.tkmybatis.rule.IdNumCryptoRule;
import top.liujingyanghui.crypto.tkmybatis.rule.PhoneCryptoRule;

import java.util.List;
import java.util.Map;

/**
 * @author : wdh
 * @since : 2022/5/23 16:31
 */
public interface UserMapper extends Mapper<User> {

    // 入参和出参都为Map情况，标识入参和出参中key为phone的属性使用PhoneCryptoRule规则去加解密
    @CryptoKey(key = "phone", rule = PhoneCryptoRule.class)
    List<Map<String, Object>> selectByMap(Map<String, String> param);

    // 入参或出参为实体情况，需要去实体中使用@CryptoClass和@CryptoString注解
    List<User> selectByEntity(@Param("user") User user);

    User selectOneByEntity(User user);

    // 入参为单个List<String>、出参为List<String>情况，使用@CryptoString注解加解密
    @CryptoString(rule = PhoneCryptoRule.class)
    List<String> selectByPhones(List<String> phoneS);

    // 入参为单个String数组、出参为String[]使用@CryptoString注解加解密
    @CryptoString(rule = PhoneCryptoRule.class)
    String[] selectByPhoneArr(String[] phoneS);

    // 入参为单个String且没有@Param注解、出参为String时，使用@CryptoString注解加解密
    @CryptoStrings({
            @CryptoString(rule = PhoneCryptoRule.class, mode = CryptoMode.ENCRYPT),
            @CryptoString(rule = IdNumCryptoRule.class, mode = CryptoMode.DECRYPT)
    })
    String selectIdNumByPhone(String phone);

    // 入参为单个String且有@Param注解需使用@CryptoKey注解加密
    @CryptoString(rule = IdNumCryptoRule.class, mode = CryptoMode.DECRYPT)
    @CryptoKey(key = "phone", rule = PhoneCryptoRule.class, mode = CryptoMode.ENCRYPT)
    String selectIdNumByPhone2(@Param("phone") String phone);

    // 入参为多个String、出参为String时的情况
    @CryptoKeys({
            @CryptoKey(key = "phone", rule = PhoneCryptoRule.class, mode = CryptoMode.ENCRYPT),
            @CryptoKey(key = "idNum", rule = IdNumCryptoRule.class, mode = CryptoMode.ENCRYPT)
    })
    @CryptoString(rule = IdNumCryptoRule.class, mode = CryptoMode.DECRYPT)
    String selectIdNumByPhoneAndIdNum(@Param("phone") String phone, @Param("idNum") String idNum);

    @CryptoKeys({
            @CryptoKey(key = "phone", rule = PhoneCryptoRule.class, mode = CryptoMode.DECRYPT),
            @CryptoKey(key = "idNum", rule = IdNumCryptoRule.class, mode = CryptoMode.DECRYPT)
    })
    List<Map<String, Object>> selectByList(List<User> users);

    // 入参为多种情况下的示例
    List<User> selectByUserParam(UserParam param);

}
